#pragma once

#include "Socket.hpp"
#include <signal.h>
#include <functional>
#include "InetAddr.hpp"

using callback_t = std::function<std::string(std::string &)>;

class Tcpserver
{
public:
    Tcpserver(uint16_t port, callback_t cb)
        : _port(port), _listensocket(std::make_unique<TcpSocket>()), _cb(cb)
    {
        _listensocket->BuildListenSocketMethod(_port);
    }

    void HandlerRequest(std::shared_ptr<Socket> sockfd, InetAddr addr)
    {
        std::string inbuffer;
        while (true)
        {
            ssize_t n = sockfd->Recv(&inbuffer, 100);
            if (n > 0)
            {
                LOG(LogLevel::INFO) << addr.ToString() << "# " << inbuffer;

                // 处理收到的数据
                std::string ret_str = _cb(inbuffer); // 检查 序列化 解包
                if (ret_str.empty())  // 空串返回
                    continue;

                sockfd->Send(ret_str);
            }
            else if (n == 0)
            {
                LOG(LogLevel::INFO) << "client " << addr.ToString() << " quit, close sockfd: " << sockfd->GetSockFd();
                break;
            }
            else
            {
                LOG(LogLevel::WARNING) << "read client " << addr.ToString() << " error, sockfd: " << sockfd->GetSockFd();
                break;
            }
        }
        sockfd->CloseSocket();
    }

    void Run()
    {
        signal(SIGCHLD, SIG_IGN);

        while (true)
        {
            // 方法 1
            InetAddr clientaddr;
            auto sockfd = _listensocket->Accept(&clientaddr);
            if (sockfd == nullptr)
            {
                // Accept 失败（如临时资源不足或信号打断），避免忙循环
                sleep(1);
                continue;
            }
            LOG(LogLevel::INFO) << "获取新链接成功, sockfd is : " << sockfd->GetSockFd() << " client addr: " << clientaddr.ToString();

            // 方法 2
            // std::string *peerip;
            // uint16_t *peerport;
            // _listensocket->AcceptConnection(peerip, peerport);
            if (fork() == 0)
            {
                // 子进程
                _listensocket->CloseSocket();
                HandlerRequest(sockfd, clientaddr);
                exit(0);
            }
            sockfd->CloseSocket();
        }
    }
    ~Tcpserver()
    {
    }

private:
    uint16_t _port;
    std::unique_ptr<Socket> _listensocket;
    callback_t _cb;
};